package algebra.query.indexing;

import java.io.OutputStream;

import java.io.PrintStream;
import java.util.ArrayList;

import entities.assertion.ConceptAssertion;
import entities.concept.Concept;
import entities.Individual;

public class IndexTreeNode {
	private ConceptAssertion ca;
	protected Individual ind;
	protected Concept data;
	protected int balance;
	protected ArrayList<IndexTreeNode> link;
	// if the right link is a thread, the flag is true, default is true as a new
	// node is always external
	protected boolean thread;

	public ArrayList<IndexTreeNode> getLink() {
		return this.link;
	}

	public IndexTreeNode(ConceptAssertion ca) {
		this.ca = ca;
		if (ca != null) {
			this.data = ca.getConcept();
			this.ind = ca.getIndividual();
		}
		balance = 2;
		thread = true;
		link = new ArrayList<IndexTreeNode>(2);
		link.add(null);
		link.add(null);
	}

	public ConceptAssertion getNodeAssertion() {
		return this.ca;
	}

	public Concept getData() {
		return data;
	}

	public Individual getID() {
		return ind;
	}

	public IndexTreeNode getLeft() {
		return link.get(0);
	}
	

	public IndexTreeNode getRight() {
		return link.get(1);
	}

	public void print(OutputStream s, String prefix, String newline) {
		PrintStream out = new PrintStream(s);
		out.print(prefix + ca + newline);
		if (prefix.equals("")) {
			prefix = "  ";
		} else {
			prefix += prefix;
		}
		if (link.get(0) != null) {
			out.print("L");
			link.get(0).print(out, prefix, newline);
		}
		if (link.get(1) != null) {
			out.print("R");
			link.get(1).print(out, prefix, newline);
		}
	}

	/*
	 * encodings: default is "UTF8", i.e., we translate unicode into text in
	 * utf-8
	 */
	public static String pathsep = "^";

	public String writeIndexNode(String prefix, String newline, String path) {
		StringBuilder sb = new StringBuilder();
		sb.append(prefix + ca.toSerializedString() + newline);
		if (prefix.equals("")) {
			// prefix = "  ";
			// prefix = new Integer(i).toString();
		} else {
			// prefix += prefix;
		}
		if (link.get(0) != null) {
			// sb.append("L");
			String mypath = path + '0';
			sb.append(mypath + pathsep
					+ link.get(0).writeIndexNode(prefix, newline, mypath));
		}
		if (link.get(1) != null & !thread) {
			// sb.append("R");
			String mypath = path + '1';
			sb.append(mypath + pathsep
					+ link.get(1).writeIndexNode(prefix, newline, mypath));
		}
		return sb.toString();
	}

	@Override
	public String toString() {
		String ret = " L="
				+ (this.link.get(0) == null ? null : this.link.get(0).ind)
				+ "[" + this.ind + "]" + "("+this.thread+")"
				+ " R=" 
				+ (this.link.get(1) == null ? null : this.link.get(1).ind);
		return ret;
	}
}
